Developer --> Technical Publications
PATHMac OS 8 Developer Documentation > Networking and Communications > AppleShare >

User Authentication Modules


Sample UAM Client

The sample code shown in Listing 3-1 opens a session with an AFP server and logs the user on.

Listing 3-1  Sample client UAM

#include <Types.h>
#include "ClientUAM.h"
#include <String.h>
#include <Resources.h>
#include <A4Stuff.h>
#include "SampleUAM.h"
#include "AFPPackets.h"
enum {
    kSampleCfg = (1 << kUseVolDlog),// The value returned by UAMOpen
};
Boolean FindStringInBuf(StringPtr,Ptr,UInt32);
long    SampleOpen(UAMArgs *theArgs);
OSStatusSampleLogin(UAMArgs *theArgs);
unsigned char commandBuffer[200];
unsigned char replyBuffer[512];
StringPtr gAFPVersion;
StringPtr FigureAFPVersion(AFPSrvrInfo *,ClientUAMCallbackRec *theCallbacks); pascal OSErr main(UAMArgs *theArgs)
{
    EnterCodeResource();
    OSErr error;
    switch(theArgs->command)
    {
        case UAMOpen:
            error = SampleOpen(theArgs);
            break;
        case kUAMPWDlog:
            error = kNotForUs;
            break;
        case kUAMLogin:
            error = SampleLogin(theArgs);
            break;
        case kUAMVSDlog:
            DebugStr("\pPut up a Volume Select dialog");
            error = noErr;
            break;
        case kUAMChgPassDlg:
            error = kNotForUs;
            break;
        case kUAMChgPass:
            error = kNotForUs;
            break;
        case kUAMGetInfoSize:
            error = kNotForUs;
            break;
        case kUAMGetInfo:
            error = kNotForUs;
            break;
        case kUAMClose:
            error = NoErr;
            break;
        default:
            error = kNotForUs;
            break;
    }
    ExitCodeResource();
    return error;
}
longSampleOpen(UAMArgs *theArgs)
{
    gAFPVersion = FigureAFPVersion(theArgs->Opt.open.srvrInfo,theArgs->callbacks);
    theArgs->result = kSampleCfg;
    return noErr;
}
OSStatus SampleLogin(UAMArgs *theArgs){
    OSStatus theError = kUAMError
    Ptr cmd;
    unsigned long cmdSize;
    Handle theUAMName;
    UAMMessag message;
    StringPtr user = theArgs->Opt.auth.userName;
    StringPtr password = theArgs->Opt.auth.password;
    if(!gAFPVersion){
        // Put up an alert and return userCanceled error
        DebugStr("\pno AFP version");
        return userCanceledErr;
    }
    if(theArgs->callbacks)
{
        commandBuffer[0] = kFPLogin;
        cmd = (Ptr) &commandBuffer[1];
        memcpy(cmd,(const char *)&gAFPVersion[0],gAFPVersion[0]+1);
        cmd += gAFPVersion[0] + 1;
        
        // Get the UAMString from the resource
        theUAMName = Get1Resource(kUAMStr,kUAMProtoName);
        if(!theUAMName)
            return ResError();// Depends on ResLoad being TRUE
        // Put the UAMString into the command buffer
        HLock(theUAMName);
        memcpy(cmd,(const char *)&((*theUAMName)[0]),(*theUAMName)[0]+1);
        cmd += (*theUAMName)[0]+1;
        HUnlock(theUAMName);
        ReleaseResource(theUAMName);
        
        // Copy in the username
        memcpy(cmd,(const char *)&user[0],user[0]+1);
        cmd += user[0]+1;

        // Test for an odd boundary
        if(((UInt32)cmd - (UInt32)commandBuffer) & 0x01)
        {
            *cmd++ = 0x00;// If an odd boundary, put in some padding
        }
        // Copy in the password (a maximum of 8 bytes)
        memcpy(cmd,(const char *)&password[0],8);
        cmd += 8;
        
        // Get the size of the command buffer
        cmdSize = (unsigned long)((unsigned long)cmd - (unsigned long)commandBuffer);
        
        message.commandCode = kOpenSession;
        message.cmdBuffer = commandBuffer;
        message.cmdBufferSize = cmdSize;
        message.replyBuffer = nil;
        message.replyBufferSize = 0;
        message.completion = nil;
        message.contextPtr = nil;
        
        //Make the login call.);
        
        theError =
        theArgs->callbacks->OpenSessionUPP(theArgs->Opt.auth.srvrAddress,nil,&message);
        if(!theError){
            theArgs->sessionRefNum = message.sessionRefNum;
        }
        theError = message.result;
        
    }
    return theError;
}

StringPtr FigureAFPVersion(AFPSrvrInfo *info,ClientUAMCallbackRec *callbacks);
{
    struct AFPClientInfo *theClientInfo = nil;
    short index;
    Ptr versBuf;
    UInt32 versBufsize;
    GetClientInfoPtr *fcn;
    
    callbacks->GetClientInfoUPP(kAFPClientInfo,(ClientInfo **)&theClientInfo);

    if(theClientInfo){
    // Go through the list of supported AFP versions and try to find them
    // in the SrvrInfoBuffer. The first match is accepted,
        versBuf = (Ptr)((UInt32)info + info->fVerCountOffset+1);
        versBufsize = kMaxAFPCommand - info->fVerCountOffset;// The largest size
        
        for(index = 0; index < theClientInfo->fNumAFPVersions; index++){
            if(FindStringInBuf
                    (theClientInfo->fAFPVersionStrs[index],versBuf,versBufsize)){
                return theClientInfo->fAFPVersionStrs[index];
            }
        }
    }
    return nil;
}
Boolean FindStringInBuf(StringPtr string, Ptr buf, UInt32 bufSize)
{
    Ptr end = buf + bufSize;
    Byte len = string[0] + 1;
    short index;
    
    while((buf < end) && (*buf++ != string[0])) ; // Scan for the proper length.

    if(!(buf < end)){
        return false;
    }
    for(index = 1; (index < len) && (buf > end); index++){
        if(*buf++ != string[index])
            return false;
    }
    if(!(buf < end)){
        return false;
    }
    return true;
}


© 1999 Apple Computer, Inc. – (Last Updated 07 May 99)